//////////////////////////////////////////////
// Function.js
//
//////////////////////////////////////////////

/// Class ------------------------------------
	
nkScriptsTests.Function = class Function extends nkDebug.TestClass
{
	static instance = new Function ("nkScriptsTests.Function") ;

	nkTests =
	{
		__testShutdown__ : function ()
		{
			nkScripts.EnvironmentManager.kill() ;
			nkScripts.ScriptManager.kill() ;
		},
		
		SetFuncGoodVisibilityFromC : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			nkDebug.TestUtils.check(!env.isFuncSet("pirnt"), "Function should not be set") ;
			env.setFunc("pirnt") ;
			nkDebug.TestUtils.check(env.isFuncSet("pirnt"), "Function should be set") ;
		},

		SetFuncGoodVisibilityFromLua : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("pirnt()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			nkDebug.TestUtils.check(!env.execute(script), "Lua execution should fail with no function set") ;
			env.setFunc("pirnt") ;
			nkDebug.TestUtils.check(env.execute(script), "Lua execution should be find with the new function added") ;
		},

		MemberFuncForObject : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("incrementI()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const resultStruct = {i: 0} ;
			const func = env.setFunc("incrementI") ;
			func.setFunction(function (stack) {resultStruct.i = 2}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(resultStruct.i === 2, "Wrong output value") ;
		},

		ParameterBool : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("useParameter(true)") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const resultStruct = {i: 0} ;
			const func = env.setFunc("useParameter") ;
			func.addParameter(nkScripts.FUNCTION_PARAMETER_TYPE.BOOL) ;
			func.setFunction(function (stack) {if (stack.getSize() > 0 && stack.get(0)._type == nkScripts.FUNCTION_PARAMETER_TYPE.BOOL) resultStruct.i = 2 ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(resultStruct.i === 2, "Wrong output value") ;
		},

		ParameterFloat : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("useParameter(5.2)") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const resultStruct = {i: 0} ;
			const func = env.setFunc("useParameter") ;
			func.addParameter(nkScripts.FUNCTION_PARAMETER_TYPE.FLOAT) ;
			func.setFunction(function (stack) {if (stack.getSize() > 0 && stack.get(0)._type == nkScripts.FUNCTION_PARAMETER_TYPE.FLOAT) resultStruct.i = stack.get(0)._valFloat ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.areNumbersEqual(resultStruct.i, 5.2, 0.001, "Wrong output value") ;
		},

		ParameterString : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("useParameter('test')") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const resultStruct = {i: ""} ;
			const func = env.setFunc("useParameter") ;
			func.addParameter(nkScripts.FUNCTION_PARAMETER_TYPE.STRING) ;
			func.setFunction(function (stack) {if (stack.getSize() > 0 && stack.get(0)._type == nkScripts.FUNCTION_PARAMETER_TYPE.STRING) resultStruct.i = stack.get(0)._valString ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(resultStruct.i === "test", "Wrong output value") ;
		},

		OutputBool : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("x = getValue()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const func = env.setFunc("getValue") ;
			func.setFunction(function (stack) {return new nkScripts.FunctionParameter (true) ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(env.getVarBool("x", false), "Wrong output value") ;
		},

		OutputFloat : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("x = getValue()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const func = env.setFunc("getValue") ;
			func.setFunction(function (stack) {return new nkScripts.FunctionParameter (3.6) ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.areNumbersEqual(3.6, env.getVarFloat("x", 0.0), 0.0001, "Wrong output value") ;
		},

		OutputString : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("x = getValue()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const func = env.setFunc("getValue") ;
			func.setFunction(function (stack) {return new nkScripts.FunctionParameter ("test") ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(env.getVarString("x", "") === "test", "Wrong output value") ;
		},

		OutputVoid : function ()
		{
			const env = nkScripts.EnvironmentManager.getInstance().createOrRetrieve("env") ;
			env.setEnvironmentFor(nkScripts.INTERPRETER.LUA) ;

			const script = nkScripts.ScriptManager.getInstance().createOrRetrieve("script") ;
			script.setTargetInterpreter(nkScripts.INTERPRETER.LUA) ;
			script.setSources("x = getValue()") ;
			nkDebug.TestUtils.check(script.load(), "Script should load") ;

			const func = env.setFunc("getValue") ;
			func.setFunction(function (stack) {return nkScripts.FunctionParameter.VOID ;}) ;

			nkDebug.TestUtils.check(env.execute(script), "Execution failure") ;
			nkDebug.TestUtils.check(!env.isVarSet("x"), "Wrong output value") ;
		}
	}
}